/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.fjala.softure.tree.array;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.fjala.softure.tree.AbstractNode;
import org.fjala.softure.tree.Node;

/**
 * This node is used in a ArrayBinaryTree.
 *
 * @author Jorge Lopez.
 * @author Manolo Alvarez.
 */
public class ArrayBinaryNode<T> extends AbstractNode<T> {

    /**
     * Children of the node.
     */
    private List<ArrayBinaryNode<T>> children;

    /**
     * Builds a ArrayBinaryNode class according to data.
     *
     * @param data value of the node.
     */
    public ArrayBinaryNode(T data) {
        super(data, new ArrayBinaryNode<T>());
        children = new ArrayList<ArrayBinaryNode<T>>(2);
    }

    /**
     * Builds a ArrayBinaryNode class with default values.
     */
    public ArrayBinaryNode() {
        super(null, new ArrayBinaryNode<T>());
        children = new ArrayList<ArrayBinaryNode<T>>(2);
    }

    /**
     * Returns the right node.
     *
     * @return right node.
     */
    public ArrayBinaryNode<T> getRight() {
        return children.get(1);
    }

    /**
     * Sets the right node.
     *
     * @param right
     */
    public void setRight(ArrayBinaryNode<T> right) {
        right.parent = this;
        children.set(1, right);
    }

    /**
     * Returns the left node.
     *
     * @return
     */
    public ArrayBinaryNode<T> getLeft() {
        return children.get(0);
    }

    /**
     * Sets the left node.
     */
    public void setLeft(ArrayBinaryNode<T> left) {
        left.parent = left;
        children.set(0, left);
    }

    @Override
    public List<Node<T>> getChildren() {
        List<Node<T>> destino = new ArrayList<Node<T>>();

        Collections.copy(destino, children);

        return destino;
    }

    @Override
    public void removeChild(Node<T> node) {
        children.remove(node);
    }

    @Override
    public T getData() {
        return data;
    }

    @Override
    public void setData(T value) {
        data = value;
    }

    @Override
    public Node<T> getParent() {
        return parent;
    }

    @Override
    public boolean hasChildren() {
        if (children.get(0) != null || children.get(1) != null) {
            return true;
        }

        return false;
    }

    @Override
    public String toString() {
        return data.toString();
    }

    @Override
    public boolean equals(Object o) {
        boolean resp = false;

        if (o instanceof ArrayBinaryNode) {
            ArrayBinaryNode node = (ArrayBinaryNode) o;
            resp = node.getData().equals(data);
        }

        return resp;
    }

    @Override
    public void addChild(Node<T> child) {
        ArrayBinaryNode<T> newNode = (ArrayBinaryNode<T>) child;
        if (getLeft() == null) {
            setLeft(newNode);
        } else {
            setRight(newNode);
        }
    }

    @Override
    public int getChildCount() {
        return children.size();
    }
}
